package wkhttp

import (
	"encoding/json"
	"errors"
	"github.com/TangSengDaoDao/TangSengDaoDaoServerLib/pkg/cache"
	"github.com/TangSengDaoDao/TangSengDaoDaoServerLib/pkg/log"
	"github.com/gin-gonic/gin"
	"github.com/opentracing/opentracing-go"
	"go.uber.org/zap"
	"net/http"
	"strconv"
	"strings"
	"sync"
)

// UserRole 用户角色
type UserRole string

const (
	// Admin 管理员
	Admin UserRole = "admin"
	// SuperAdmin 超级管理员
	SuperAdmin UserRole = "superAdmin"
)

// WKHttp WKHttp
type WKHttp struct {
	r    *gin.Engine
	pool sync.Pool
}

var ErrorMessages map[string]int
var CodeEnMessages map[int]string
var CodeCnMessages map[int]string

func init() {
	ErrorMessages = map[string]int{
		"查询管理者们的uid失败！":           60001,
		"数据格式有误！":                 60002,
		"事务提交失败！":                 60003,
		"查询消息失败！":                 60004,
		"添加已读数据失败！":               60005,
		"查询已读列表失败！":               60006,
		"查询用户数据失败！":               60007,
		"从缓存中获取消息扩展版本失败！":         60008,
		"缓存最大的消息扩展版本失败！":          60009,
		"同步消息扩展数据失败！":             60010,
		"修改语音已读状态失败！":             60011,
		"发送同步命令失败！":               60012,
		"更新消息置顶状态失败！":             60013,
		"修改消息扩展置顶状态错误":            60014,
		"通过qrcode获取用户信息失败！":       60015,
		"添加举报数据失败！":               60016,
		"查询类别失败！":                 60017,
		"查询机器人失败！":                60018,
		"查询当前用户信息失败！":             60019,
		"请求验证微信access_token错误":    60020,
		"解码微信access_token返回数据失败！": 60021,
		"获取微信用户资料请求错误":            60022,
		"解码微信用户信息返回数据失败！":         60023,
		"发送指令失败！":                 60024,
		"获取用户在线状态失败！":             60025,
		"查询指定在线设备失败！":             60026,
		"获取我的个人数据失败！":             60027,
		"频道id不能为空！":               60028,
		"视频名称不能为空":                60029,
		"查询最新版本错误":                60030,
		"sid不能为空！":                60031,
		"查询app模块错误":               60032,
		"数据不能为空":                  60033,
		"图片数量不能大于9！":              60034,
		"群ID不能为空":                 60035,
		"查询群资料错误":                 60036,
		"查询用户群内身份错误":              60037,
		"查询群列表错误":                 60038,
		"查询群数量错误":                 60039,
		"不支持代发消息":                 60040,
		"发送者token不能为空":            60041,
		"接受channelID不能为空":         60042,
		"同步消息扩展失败！":               60043,
		"发送者不能为空":                 60044,
		"频道ID不能为空！":               60045,
		"开启事务失败！":                 60046,
		"token不能为空！":              60047,
		"获取登录信息失败！":               60048,
		"用户不存在！":                  60049,
		"查询频道类型不能为空":              60050,
		"查询举报列表错误":                60051,
		"发送stream start消息失败！":     60052,
		"机器人ID不能为空":               60053,
		"查询机器人菜单错误":               60054,
		"查询用户数量错误":                60055,
		"查询某天用户注册量错误":             60056,
		"退出web设备失败":               60057,
		"退出PC设备失败":                60058,
		"删除设备token失败！":            60059,
		"删除设备失败！":                 60060,
		"查询设备列表失败！":               60061,
		"好友ID不能为空":                60062,
		"查询申请记录错误":                60063,
		"redis set error":         60064,
		"获取登录状态失败！":               60065,
		"登录状态已过期！":                60066,
		"code不能为空":                60067,
		"请求数据格式有误！":               60068,
		"查询登录用户信息错误":              60069,
		"数据库事务开启失败！":              60070,
		"请求用户uid不能为空":             60071,
		"查询用户在线设备信息错误":            60072,
		"查询用户设置失败！":               60073,
		"暂不支持用户名注册":               60074,
		"用户名不能为空！":                60075,
		"用户名必须在8-22位":             60076,
		"分类不能为空":                  60077,
		"添加用户通讯录联系人错误":            60078,
		"cmd不能为空！":                60079,
		"删除的应用ID不能为空":             60080,
		"删除使用记录错误":                60081,
		"查询登录用户加入群成员信息错误":         60082,
		"同步提醒项失败！":                60083,
		"发送同步提醒项cmd失败！":           60084,
		"提交事务失败！":                 60085,
		"更新提醒项版本失败！":              60086,
		"添加done失败！":               60087,
		"查询消息回应数据错误":              60088,
		"查询用户消息扩展错误":              60089,
		"查询频道内的消息失败！":             60090,
		"删除置顶消息错误":                60091,
		"查询频道偏移量失败！":              60092,
		"查询用户消息扩展字段失败！":           60093,
		"用户无权清空置顶消息":              60094,
		"发送解散群消息错误":               60095,
		"负荷数据不是json格式！":           60096,
		"发送cmd失败！":                60097,
		"取消置顶消息错误":                60098,
		"新增置顶消息错误":                60099,
		"开启事务错误":                  60100,
		"查询置顶消息错误":                60101,
		"置顶数量已达到上限":               60102,
		"查询当前置顶消息数量错误":            60103,
		"查询配置错误":                  60104,
		"该消息不存在或已删除":              60105,
		"查询消息扩展信息错误":              60106,
		"该不存在或已删除":                60107,
		"查询消息错误":                  60108,
		"普通成员不允许置顶消息":             60109,
		"查询用户在群内权限错误":             60110,
		"群不存在或已删除":                60111,
		"查询群组信息错误":                60112,
		"消息seq不合法":                60113,
		"消息ID不能为空！":               60114,
		"命令发送失败！":                 60115,
		"查询群聊信息失败！":               60116,
		"查询用户详情失败！":               60117,
		"查询频道设置错误":                60118,
		"获取最近会话失败！":               60119,
		"查询频道设置失败！":               60120,
		"查询用户频道偏移量失败！":            60121,
		"查询群设置信息失败！":              60122,
		"查询最近会话扩展失败！":             60123,
		"查询有效群失败！":                60124,
		"同步离线后的最近会话失败！":           60125,
		"获取用户超大群失败！":              60126,
		"插入设备偏移数据失败！":             60127,
		"查询用户偏移量失败！":              60128,
		"查询用户设备偏移量失败！":            60129,
		"设置设备最近会话最大版本号失败！":        60130,
		"获取用户最近会很最大版本失败！":         60131,
		"获取缓存的最近会话版本号失败！":         60132,
		"删除最近会话失败！":               60133,
		"发送同步扩展会话cmd失败！":          60134,
		"添加或更新最近会话扩展失败！":          60135,
		"用户名格式错误！":                60136,
		"系统异常！":                   60137,
		"查询用户红点错误":                60138,
		"无权查看！":                   60139,
		"需要验证手机号码！":               60140,
		"解码二维码信息失败！":              60141,
		"获取uuid绑定的二维码信息失败！":       60142,
		"设置登录uuid失败！":             60143,
		"用户没有QRVercode，非法操作！":     60144,
		"调用IM服务失败！":               60145,
		"绑定手机号错误！":                60146,
		"该手机号已使用":                 60147,
		"上传用户头像失败！":               60148,
		"发送频道更改消息错误！":             60149,
		"重新设置token缓存失败！":          60150,
		"修改用户资料失败":                60151,
		"不允许编辑！":                  60152,
		"不允许更新！":                  60153,
		"名字不能为空！":                 60154,
		"用户短编号只能修改一次":             60155,
		"已存在，请换一个！":               60156,
		"短号须以字母开头，仅支持使用6～20个字母、数字、下划线、减号自由组合": 60157,
		"该账号不存在":             60158,
		"修改聊天密码失败":           60159,
		"登录密码不能为空！":          60160,
		"聊天密码不能为空":           60161,
		"修改用户锁屏密码错误":         60162,
		"锁屏时间不能大于60分钟":       60163,
		"锁屏时间不能小于0":          60164,
		"修改登录密码错误":           60165,
		"设置短编号被使用失败！":        60166,
		"获取短编号失败！":           60167,
		"注册失败！":              60168,
		"数据库事物提交失败":          60169,
		"创建数据库事物失败":          60170,
		"注册通道暂不开放":           60171,
		"退出登陆设备失败":           60172,
		"注销账号申请已提交，请勿重复申请":   60173,
		"注销账号错误":             60174,
		"登录用户不存在！":           60175,
		"添加或更新登录设备信息失败！":     60176,
		"解码登录设备信息失败！":        60177,
		"登录设备已过期，请重新登录":      60178,
		"获取登录设备缓存失败！":        60179,
		"验证短信失败":             60180,
		"发送短信验证码失败":          60181,
		"该手机号未注册":            60182,
		"仅仅支持中国大陆手机号注册！":     60183,
		"查询黑名单列表失败！":         60184,
		"移除黑名单失败！":           60185,
		"提交数据库失败！":           60186,
		"更新好友的版本号失败！":        60187,
		"添加黑名单失败！":           60188,
		"设置黑名单失败！":           60189,
		"添加用户设置失败！":          60190,
		"添加黑名单的用户ID不能空！":     60191,
		"更新二维码信息失败！":         60192,
		"扫描者与授权者不是同一个用户！":    60193,
		"授权码不是登录授权码！":        60194,
		"解码授权信息失败！":          60195,
		"授权码失效或不存在！":         60196,
		"获取授权信息失败！":          60197,
		"授权码不能为空！":           60198,
		"此账号已经被封禁！":          60199,
		"设置uidtoken缓存失败！":    60200,
		"清除旧token数据错误":       60201,
		"获取旧token错误":         60202,
		"设置token缓存失败！":       60203,
		"缓存登录设备失败！":          60204,
		"更新用户登录设备失败":         60205,
		"查询是否存在的设备失败":        60206,
		"登录设备信息不能为空！":        60207,
		"不支持当前客户端Ip访问！":      60208,
		"该用户已被禁用":            60209,
		"密码长度必须小于16位！":       60210,
		"密码长度不能小于6位！":        60211,
		"密码不能为空！":            60212,
		"验证码不能为空":            60213,
		"手机号不能为空！":           60214,
		"区号不能为空！":            60215,
		"更新禁言成员新消息错误":        60216,
		"查询禁言成员信息错误":         60217,
		"设置IM黑名单错误":          60218,
		"禁言用户错误":             60219,
		"禁言成员时长参数错误":         60220,
		"解除用户禁言错误":           60221,
		"操作用户权限不够":           60222,
		"登录用户不在本群内无法操作":      60223,
		"查询登录用户群内信息错误":       60224,
		"发送群成员被踢消息失败！":       60225,
		"调用IM的移除订阅者接口失败！":    60226,
		"开启群成员头像更新事件失败！":     60227,
		"查询群头像是否用户上传过失败！":    60228,
		"查询最早加入的成员信息失败！":     60229,
		"记录踢人失败！":            60230,
		"删除群成员失败！":           60231,
		"查询被删除的群成员信息错误":      60232,
		"管理员不能删除群主":          60233,
		"管理员不能删除管理员":         60234,
		"被删除者不在此群内":          60235,
		"群成员不能为空！":           60236,
		"更新群成员信息失败！":         60237,
		"成员信息不存在！":           60238,
		"查询成员信息失败！":          60239,
		"只有管理员才能修改其他人的成员信息！": 60240,
		"新群主添加白名单失败！":        60241,
		"修改成员禁言时长失败！":        60242,
		"更新成创建者失败！":          60243,
		"更新成普通成员失败！":         60244,
		"转让的用户没在群内！":         60245,
		"转让用户不存在或已注销！":       60246,
		"查询转让用户失败！":          60247,
		"不是群主，不能转让":          60248,
		"发送命令消息失败！":          60249,
		"设置白名单失败！":           60250,
		"更新成员为管理员失败！":        60251,
		"只有创建者才能设置管理员！":      60252,
		"查询是否是创建者失败！":        60253,
		"添加的成员已在群内或在群黑名单内":   60254,
		"群不存在！":              60255,
		"开启事件失败！":            60256,
		"添加群失败！":             60257,
		"成员用户信息不存在！":         60258,
		"查询成员用户信息失败！":        60259,
		"群成员人数超过上限":          60260,
		"不支持将`系统账号`加入群聊":     60261,
		"查询应用设置错误":           60262,
		"添加用户非好友关系，请先添加好友":   60263,
		"查询用户好友错误":           60264,
		"当天建群数量已达上限":         60265,
		"无权创建！":              60266,
		"上传文件失败！":            60267,
		"读取文件失败！":            60268,
		"数据格式不正确！":           60269,
		"查询我保存的群聊失败":         60270,
		"同步成员信息失败！":          60271,
		"超大群不支持同步群成员！":       60272,
		"群不存在不能同步成员！":        60273,
		"查询群信息失败！":           60274,
		"发送群头像更新命令失败！":       60275,
		"头像修改失败！":            60276,
		"只有群管理者才能修改！":        60277,
		"查询是否是群管理者失败！":       60278,
		"没有需要更新的属性！":         60279,
		"查询成员列表失败！":          60280,
		"取消保存群聊错误":           60281,
		"修改群状态错误":            60282,
		"用户无权执行此操作":          60283,
		"该用户已存在":             60284,
		"验证码错误":              60285,
		"邀请码不存在":             60286,
		"邀请码不能为空":            60287,
		"当前注册方式未开通":          60288,
		"不支持账号密码登录！":         60289,
		"不支持当前客户端登录！":        60290,
		"密码不正确！":             60291,
		"此账号不允许登录":           60292,
		"查询用户信息失败！":          60293,
		"当前登录方式未开通":          60294,
		"查询使用记录错误":           60295,
		"头像读取失败！":            60296,
		"用户需要验证":             60297,
		"修改用户是否修改头像错误！":      60298,
		"通过short_no查询用户失败！":  60299,
		"id不能为空":             60300,
		"删除申请记录错误":           60301,
		"查询好友申请列表错误":         60302,
		"用户uid不能为空":          60303,
		"删除好友错误":             60304,
		"修改好友单项关系错误":         60305,
		"发送删除好友事件失败":         60306,
		"查询用户好友设置错误":         60307,
		"发送频道更新命令失败！":        60308,
		"发送删除好友的cmd失败！":      60309,
		"不能添加自己为好友！":         60310,
		"查询用户角色权限错误":         60311,
		"登录用户没有权限添加好友！":      60312,
		"不可添加好友！":            60313,
		"查询是否是好友失败！":         60314,
		"已经是好友，不能再申请！":       60315,
		"查询接收者用户信息失败！":       60316,
		"接收好友请求的用户不存在！":      60317,
		"查询好友信息错误":           60318,
		"好友信息不存在":            60319,
		"设置申请token失败！":       60320,
		"查询好友申请记录错误":         60321,
		"查询用户通讯录红点信息错误":      60322,
		"新增好友申请记录错误":         60323,
		"修改好友申请记录错误":         60324,
		"新增用户通讯录红点信息错误":      60325,
		"修改用户通讯录红点信息错误":      60326,
		"提交事物错误":             60327,
		"发送好友申请失败！":          60328,
		"获取好友申请token的信息失败！":  60329,
		"获取token信息错误":        60330,
		"好友申请已过期":            60331,
		"当前用户不存在或已注销！":       60332,
		"查询申请人用户信息失败！":       60333,
		"申请人不存在":             60334,
		"好友申请无效或已过期！":        60335,
		"设置消息自动删除失败":         60336,
		"添加好友失败！":            60337,
		"修改好友关系失败":           60338,
		"查询被添加者是否是好友失败！":     60339,
		"发送好友确认事件失败":         60340,
		"发送消息失败！":            60341,
		"发送通过好友请求消息失败！":      60342,
		"发送接受好友请求消息失败！":      60343,
		"删除缓存数据错误":           60344,
		"同步好友信息错误！":          60345,
		"获取用户详情失败！":          60346,
		"查询好友数据失败！":          60347,
		"查询设置信息失败！":          60348,
		"修改用户备注错误！":          60349,
		"修改备注-发送频道更新消息失败":    60350,
		"好友的ID不能为空！":         60351,
		"接收申请的token不能为空！":    60352,
		"频道Id不能为空！":          60353,
		"频道不存在！":             60354,
		"查询群的创建者或管理员错误":      60355,
		"没有权限设置":             60356,
		"查询频道最大序列号失败！":       60357,
		"设置频道最大偏移序列号失败":      60358,
		"发送清空频道聊天记录命令失败！":    60359,
		"查询频道失败！":            60360,
		"查询群成员错误":            60361,
		"查询群成员在线数量错误":        60362,
		"参数错误":               60363,
		"设置失败":               60364,
		"查询所有app模块错误":        60365,
		"查询所有聊天背景错误":         60366,
		"获取验证码错误":            60367,
		"添加更新记录错误":           60368,
		"平台类型不能为空":           60369,
		"版本号不能为空":            60370,
		"查询版本列表错误":           60371,
		"查询总数量错误":            60372,
		"请输入版本号":             60373,
		"请输入更新说明":            60374,
		"请输入升级平台":            60375,
		"Android平台请传入下载地址":   60376,
		"图片不能为空！":            60377,
		"组合图片失败！":            60378,
		"签名复制文件错误":           60379,
		"访问路径不能为空":           60380,
		"文件类型不能为空":           60381,
		"上传路径不能为空":           60382,
		"文件类型错误":             60383,
		"群编号不能为空":            60384,
		"获取二维码信息失败！":         60385,
		"二维码或已过期！":           60386,
		"不支持的扫码类型！":          60387,
		"处理请求失败！":            60388,
		"设置扫描登录二维码信息失败！":     60389,
		"举报类别不能为空！":          60390,
	}
	CodeEnMessages = map[int]string{
		-1:    "The network has gone astray~",
		60049: "The account or password is incorrect, please check!",
		60066: "Login status has expired!",
		60074: "Username registration is not currently supported!",
		60075: "Username cannot be empty!",
		60076: "Username must be between 8~22 characters!",
		60102: "The number of pins has reached the upper limit!",
		60136: "Wrong username format!",
		60139: "No permission to view!",
		60147: "This phone number is already in use!",
		60148: "Failed to upload user avatar!",
		60156: "Account already exists, please change it!",
		60157: "The account number must start with two letters and only supports a free combination of 6 to 20 letters, numbers, underscores, and minus signs!",
		60165: "Failed to modify login password, please try again!",
		60173: "The application for account cancellation has been submitted. Please do not apply again!",
		60175: "The account or password is incorrect, please check!",
		60178: "Your mobile login status has expired, please log in again!",
		60182: "The account or password is incorrect, please check!",
		60199: "The user has been disabled!",
		60208: "Current IP access is not supported!",
		60209: "The user has been disabled!",
		60210: "The password must be less than 16 characters long!",
		60211: "The password length cannot be less than 6 characters!",
		60212: "Password cannot be empty!",
		60213: "Verification code cannot be empty!",
		60214: "Mobile phone number cannot be empty!",
		60215: "Area code cannot be empty!",
		60260: "Number of group members exceeds upper limit!",
		60261: "Adding system accounts to group chats is not supported!",
		60265: "The number of groups created today has reached the upper limit!",
		60266: "No permission to create!",
		60284: "This user already exists!",
		60285: "Verification code error!",
		60288: "The current registration method is not available!",
		60289: "Login with account and password is not supported!",
		60290: "Current client login is not supported!",
		60291: "The account or password is incorrect, please check!",
		60294: "Current login method is not enabled!",
		60312: "The current user does not have permission to add friends!",
		60315: "Already your friend, can't apply again!",
		60331: "Already your friend, can't apply again!",
		60335: "Friend request has expired!",
		60386: "The QR code has expired!",
	}
	CodeCnMessages = map[int]string{
		-1:    "网络开小差了~",
		60049: "账号或密码错误，请检查！",
		60066: "登录状态已过期！",
		60074: "暂不支持用户名注册！",
		60075: "用户名不能为空！",
		60076: "用户名必须在 8-22 位！",
		60102: "置顶数量已达到上限",
		60136: "用户名格式错误！",
		60139: "无权查看！",
		60147: "该手机号已使用！",
		60148: "上传用户头像失败！",
		60156: "账号已存在，请更换！",
		60157: "账号须以两个字母开头，仅支持使用 6～20 个字母、数字、下划线、减号自由组合！",
		60165: "修改登录密码失败，请重试！",
		60173: "注销账号申请已提交，请勿重复申请！",
		60175: "账号或密码错误，请检查！",
		60178: "手机端登录状态已过期，请重新登录！",
		60182: "账号或密码错误，请检查！",
		60199: "该用户已被禁用！",
		60208: "不支持当前IP访问！",
		60209: "该用户已被禁用！",
		60210: "密码长度必须小于 16 位！",
		60211: "密码长度不能小于 6 位！",
		60212: "密码不能为空！",
		60213: "验证码不能为空！",
		60214: "手机号不能为空！",
		60215: "区号不能为空！",
		60260: "群成员人数超过上限！",
		60261: "不支持将系统账号加入群聊！",
		60265: "当天建群数量已达上限！",
		60266: "无权创建！",
		60284: "该用户已存在！",
		60285: "验证码错误！",
		60288: "当前注册方式未开通！",
		60289: "不支持账号密码登录！",
		60290: "不支持当前客户端登录！",
		60291: "账号或密码错误，请检查！",
		60294: "当前登录方式未开通！",
		60312: "当前用户没有权限添加好友！",
		60315: "已经是好友，不能再申请！",
		60331: "好友申请已过期！",
		60335: "好友申请已过期！",
		60386: "二维码已过期！",
	}
}

// New New
func New() *WKHttp {
	l := &WKHttp{
		r:    gin.New(),
		pool: sync.Pool{},
	}
	l.r.Use(gin.Recovery())
	l.pool.New = func() interface{} {
		return allocateContext()
	}
	return l
}

func (l *WKHttp) GetGinRoute() *gin.Engine {
	return l.r
}

func allocateContext() *Context {
	return &Context{Context: nil, lg: log.NewTLog("context")}
}

// Context Context
type Context struct {
	*gin.Context
	lg log.Log
}

func (c *Context) reset() {
	c.Context = nil
}

// ResponseError ResponseError
func (c *Context) ResponseError(err error) {
	code := GetErrorCode(err.Error())
	lang := c.GetHeader("lang")
	msg := GetErrorMessage(code, lang)
	if msg == "网络开小差了~" || msg == "The network has gone astray~" {
		msg = "toast：$" + strconv.Itoa(code) + " " + msg
	}
	c.JSON(http.StatusBadRequest, gin.H{
		"msg":    msg,
		"status": code,
	})
}

// ResponseErrorf ResponseErrorf
func (c *Context) ResponseErrorf(msg string, err error) {
	if err != nil {
		c.lg.Error(msg, zap.Error(err), zap.String("path", c.FullPath()))
	}
	code := GetErrorCode(msg)
	lang := c.GetHeader("lang")
	msg = GetErrorMessage(code, lang)
	if msg == "网络开小差了~" || msg == "The network has gone astray~" {
		msg = "toast：$" + strconv.Itoa(code) + " " + msg
	}
	c.JSON(http.StatusBadRequest, gin.H{
		"msg":    msg,
		"status": code,
	})
}

// ResponseErrorWithStatus ResponseErrorWithStatus
func (c *Context) ResponseErrorWithStatus(err error, status int) {
	c.JSON(http.StatusBadRequest, gin.H{
		"msg":    err.Error(),
		"status": status,
	})
}

// GetPage 获取页参数
func (c *Context) GetPage() (pageIndex int64, pageSize int64) {
	pageIndex, _ = strconv.ParseInt(c.Query("page_index"), 10, 64)
	pageSize, _ = strconv.ParseInt(c.Query("page_size"), 10, 64)
	if pageIndex <= 0 {
		pageIndex = 1
	}
	if pageSize <= 0 {
		pageSize = 15
	}
	return
}

// ResponseOK 返回成功
func (c *Context) ResponseOK() {
	c.JSON(http.StatusOK, gin.H{
		"status": http.StatusOK,
	})
}

func (c *Context) StreamResponse(data interface{}) {
	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.WriteHeader(http.StatusOK)

	encoder := json.NewEncoder(c.Writer)
	encoder.SetEscapeHTML(false)
	if err := encoder.Encode(data); err != nil {
		// 处理错误
	}
}

// Response Response
func (c *Context) Response(data interface{}) {
	c.JSON(http.StatusOK, data)
}

// ResponseWithStatus ResponseWithStatus
func (c *Context) ResponseWithStatus(status int, data interface{}) {
	c.JSON(status, data)
}

// GetLoginUID 获取当前登录的用户uid
func (c *Context) GetLoginUID() string {
	return c.MustGet("uid").(string)
}

// GetAppID appID
func (c *Context) GetAppID() string {
	return c.GetHeader("appid")
}

// GetLoginName 获取当前登录的用户名字
func (c *Context) GetLoginName() string {
	return c.MustGet("name").(string)
}

// GetLoginRole 获取当前登录用户的角色
func (c *Context) GetLoginRole() string {
	return c.GetString("role")
}

// GetSpanContext 获取当前请求的span context
func (c *Context) GetSpanContext() opentracing.SpanContext {
	return c.MustGet("spanContext").(opentracing.SpanContext)
}

// CheckLoginRole 检查登录角色权限
func (c *Context) CheckLoginRole() error {
	role := c.GetLoginRole()
	if role == "" {
		return errors.New("登录用户角色错误")
	}
	if role != string(Admin) && role != string(SuperAdmin) {
		return errors.New("用户无权执行此操作")
	}
	return nil
}

// CheckLoginRoleIsSuperAdmin 检查登录用户为超级管理员
func (c *Context) CheckLoginRoleIsSuperAdmin() error {
	role := c.GetLoginRole()
	if role == "" {
		return errors.New("登录用户角色错误")
	}
	if role != string(SuperAdmin) {
		return errors.New("用户无权执行此操作")
	}
	return nil
}

func (c *Context) IsSuperAdmin() bool {
	return c.GetLoginRole() == string(SuperAdmin)
}

// HandlerFunc HandlerFunc
type HandlerFunc func(c *Context)

// WKHttpHandler WKHttpHandler
func (l *WKHttp) WKHttpHandler(handlerFunc HandlerFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		hc := l.pool.Get().(*Context)
		hc.reset()
		hc.Context = c
		defer l.pool.Put(hc)

		handlerFunc(hc)

		//handlerFunc(&Context{Context: c})
	}
}

// Run Run
func (l *WKHttp) Run(addr ...string) error {
	return l.r.Run(addr...)
}

func (l *WKHttp) RunTLS(addr, certFile, keyFile string) error {
	return l.r.RunTLS(addr, certFile, keyFile)
}

// POST POST
func (l *WKHttp) POST(relativePath string, handlers ...HandlerFunc) {
	l.r.POST(relativePath, l.handlersToGinHandleFuncs(handlers)...)
}

// GET GET
func (l *WKHttp) GET(relativePath string, handlers ...HandlerFunc) {
	l.r.GET(relativePath, l.handlersToGinHandleFuncs(handlers)...)
}

// Any Any
func (l *WKHttp) Any(relativePath string, handlers ...HandlerFunc) {
	l.r.Any(relativePath, l.handlersToGinHandleFuncs(handlers)...)
}

// Static Static
func (l *WKHttp) Static(relativePath string, root string) {
	l.r.Static(relativePath, root)
}

// LoadHTMLGlob LoadHTMLGlob
func (l *WKHttp) LoadHTMLGlob(pattern string) {
	l.r.LoadHTMLGlob(pattern)
}

// UseGin UseGin
func (l *WKHttp) UseGin(handlers ...gin.HandlerFunc) {
	l.r.Use(handlers...)
}

// Use Use
func (l *WKHttp) Use(handlers ...HandlerFunc) {
	l.r.Use(l.handlersToGinHandleFuncs(handlers)...)
}

// ServeHTTP ServeHTTP
func (l *WKHttp) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	l.r.ServeHTTP(w, req)
}

// Group Group
func (l *WKHttp) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
	return newRouterGroup(l.r.Group(relativePath, l.handlersToGinHandleFuncs(handlers)...), l)
}

// HandleContext HandleContext
func (l *WKHttp) HandleContext(c *Context) {
	l.r.HandleContext(c.Context)
}

func (l *WKHttp) handlersToGinHandleFuncs(handlers []HandlerFunc) []gin.HandlerFunc {
	newHandlers := make([]gin.HandlerFunc, 0, len(handlers))
	if handlers != nil {
		for _, handler := range handlers {
			newHandlers = append(newHandlers, l.WKHttpHandler(handler))
		}
	}
	return newHandlers
}

// AuthMiddleware 认证中间件
func (l *WKHttp) AuthMiddleware(cache cache.Cache, tokenPrefix string) HandlerFunc {

	return func(c *Context) {
		token := c.GetHeader("token")
		if token == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
				"msg": "token不能为空，请先登录！",
			})
			return
		}
		uidAndName := GetLoginUID(token, tokenPrefix, cache)
		if strings.TrimSpace(uidAndName) == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
				"msg": "请先登录！",
			})
			return
		}
		uidAndNames := strings.Split(uidAndName, "@")
		if len(uidAndNames) < 2 {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
				"msg": "token有误！",
			})
			return
		}
		c.Set("uid", uidAndNames[0])
		c.Set("name", uidAndNames[1])
		if len(uidAndNames) > 2 {
			c.Set("role", uidAndNames[2])
		}
		// c.Next()
	}
}

// GetLoginUID GetLoginUID
func GetLoginUID(token string, tokenPrefix string, cache cache.Cache) string {
	uid, err := cache.Get(tokenPrefix + token)
	if err != nil {
		return ""
	}
	return uid
}

// RouterGroup RouterGroup
type RouterGroup struct {
	*gin.RouterGroup
	L *WKHttp
}

func newRouterGroup(g *gin.RouterGroup, l *WKHttp) *RouterGroup {
	return &RouterGroup{RouterGroup: g, L: l}
}

// POST POST
func (r *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) {
	r.RouterGroup.POST(relativePath, r.L.handlersToGinHandleFuncs(handlers)...)
}

// GET GET
func (r *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) {
	r.RouterGroup.GET(relativePath, r.L.handlersToGinHandleFuncs(handlers)...)
}

// DELETE DELETE
func (r *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) {
	r.RouterGroup.DELETE(relativePath, r.L.handlersToGinHandleFuncs(handlers)...)
}

// PUT PUT
func (r *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) {
	r.RouterGroup.PUT(relativePath, r.L.handlersToGinHandleFuncs(handlers)...)
}

// CORSMiddleware 跨域
func CORSMiddleware() HandlerFunc {
	return func(c *Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, token, accept, origin, Cache-Control, X-Requested-With, appid, noncestr, sign, timestamp, signature")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT,DELETE,PATCH")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

func LogRequestHeadersMiddleware() HandlerFunc {
	return func(c *Context) {
		headers := make(map[string]string)
		for k, v := range c.Request.Header {
			headers[k] = strings.Join(v, ",")
		}

		headerJSON, _ := json.Marshal(headers)
		c.lg.Info("请求头信息",
			zap.String("path", c.Request.URL.Path),
			zap.String("method", c.Request.Method),
			zap.String("headers", string(headerJSON)),
		)

		c.Next()
	}
}

// GetErrorCode 获取错误码
func GetErrorCode(msg string) int {
	if code, ok := ErrorMessages[msg]; ok {
		return code
	}
	return -1 // 或者返回一个默认错误码
}

// GetErrorMessage 获取错误消息
func GetErrorMessage(code int, lang string) string {
	if lang == "cn" {
		if msg, ok := CodeCnMessages[code]; ok {
			return msg
		} else {
			return "网络开小差了~"
		}
	} else {
		if msg, ok := CodeEnMessages[code]; ok {
			return msg
		} else {
			return "The network has gone astray~"
		}
	}
}
